#!/usr/bin/python2.5
#
# Copyright 2010 Google Inc. All Rights Reserved.
"""Robot that creates issue tracker for an issue."""

import logging
import time
import urlparse
from datetime import datetime
from datetime import timedelta

from waveapi import appengine_robot_runner
from waveapi import element
from waveapi import events
from waveapi import robot
from waveapi import util
from waveapi import blip

CONSUMER_KEY = 'XXX'
CONSUMER_SECRET = 'XXX'
ROBOT_KEY = 'robot.football.request'
ROBOT_ID = u'football-fever@appspot.com'
SANDBOX_DOMAIN = 'wavesandbox.com'
PREVIEW_DOMAIN = 'wave.google.com/wave'
SANDBOX_RPC_BASE = 'http://sandbox.gmodules.com/api/rpc'
PREVIEW_RPC_BASE = 'http://gmodules.com/api/rpc'
WELCOME_TEXT = 'Welcome to your personal match wave, where you can make predictions with your friends or colleagues. To add them to this wave, just click the "+" button above.'
WELCOME_TEXT_PARTY = 'Welcome to your party wave, where you can plan a viewing party to watch the match together with your friends. To add them to this wave, just click the "+" button above.'

#TODO Delete these.
BUG_KEY = 'robot.football.id'

# Final links.
FAV_PLAYER_URL = 'http://football-fever.appspot.com/static/player.xml'
ICON = 'http://football-fever.appspot.com/images/icon.png'
LOADING_GADGET_URL = 'http://football-fever.appspot.com/static/loading.xml'
MAP_GADGET_URL = 'http://google-wave-resources.googlecode.com/svn/trunk/samples/extensions/gadgets/mappy/mappy.xml'
POLL_GADGET_URL = 'http://football-fever.appspot.com/static/polly.xml'
PREDICTION_GADGET_URL = 'http://football-fever.appspot.com/static/prediction.xml'
RSS_GADGET_URL = 'http://football-fever.appspot.com/static/rss.xml'
TWITTER_URL = 'http://football-fever.appspot.com/static/twitter.xml'
YESNO_GADGET_URL = 'http://football-fever.appspot.com/static/yesno.xml'



def GetRPCBase(domain):
  logging.info('GetRPCBase -->' + domain)
  if domain.find(SANDBOX_DOMAIN) != -1:
    return SANDBOX_RPC_BASE
  if domain.find(PREVIEW_DOMAIN) != -1:
    return PREVIEW_RPC_BASE
  else:
    return PREVIEW_RPC_BASE


def OnWaveletSelfAdded(event, wavelet):
  """Called when the annotation changes."""
  logging.info('WaveletSelfAdded')
  pass


def appendAnnotatedText(bl, text, name, value):
  """Append text to a blip with a single bundled annotation."""
  bl.append(text+'\n', bundled_annotations=[(name, value)])


def appendTitle(bl, text):
  """ Append the text with title specific font size."""
  bundle = [
      (blip.Annotation.FONT_FAMILY, 'Arial'),
      (blip.Annotation.FONT_WEIGHT, 'bold'),
      (blip.Annotation.FONT_SIZE, '18px')]
  bl.append('\n' + text + '\n', bundled_annotations=bundle)


def appendSectionTitle(bl, text):
  """ Append the text with title specific font size."""
  bundle = [
      (blip.Annotation.FONT_FAMILY, 'Arial'),
      (blip.Annotation.FONT_WEIGHT, 'bold'),
      (blip.Annotation.FONT_SIZE, '16px')]
  bl.append(text + '\n\n', bundled_annotations=bundle)


def appendSubTitle(bl, text):
  """ Append the text with title specific font size."""
  bundle = [
      (blip.Annotation.FONT_FAMILY, 'Arial'),
      (blip.Annotation.FONT_WEIGHT, 'bold'),
      (blip.Annotation.FONT_SIZE, '14px')]
  bl.append(text + '\n', bundled_annotations=bundle)


def appendContent(bl, text):
  """ Append the text with title specific font size."""
  bundle = [
      (blip.Annotation.FONT_FAMILY, 'Arial'),
      (blip.Annotation.FONT_WEIGHT, 'bold'),
      (blip.Annotation.FONT_SIZE, '12px')]
  bl.append(text + '\n', bundled_annotations=bundle)

def appendContentInline(bl, text):
  """ Append the text with title specific font size."""
  bundle = [
      (blip.Annotation.FONT_FAMILY, 'Arial'),
      (blip.Annotation.FONT_SIZE, '12px')]
  bl.append(text, bundled_annotations=bundle)

def appendLink(bl, text, link):
  """ Append the text with title specific font size."""
  bundle = [
      (blip.Annotation.FONT_FAMILY, 'Arial'),
      ('link/manual', link),
      (blip.Annotation.FONT_SIZE, '12px')]
  bl.append(text + '\n', bundled_annotations=bundle)


def appendWelcomeInfo(bl, statium, event_date, welcome_text):
  """ Append the text with title specific font size."""
  text = statium + ', at ' + event_date.strftime('%A, %d %B %Y %I:%M%p') + ' (South Africa Standard Time)'
  bundle = [
      (blip.Annotation.FONT_FAMILY, 'Arial'),
      (blip.Annotation.FONT_WEIGHT, 'normal'),
      (blip.Annotation.FONT_SIZE, '12px')]
  bl.append(text + '\n\n', bundled_annotations=bundle)
  bl.append(welcome_text + '\n\n', bundled_annotations=bundle)


def addLineBreak(bl):
  """ Append the text with title specific font size."""
  bundle = [
      (blip.Annotation.FONT_SIZE, '16px')]
  bl.append('\n\n', bundled_annotations=bundle)


def LoadingGadgetStateChanged(event, wavelet, loading_gadget):
  logging.info(util.serialize(loading_gadget))
  team_info = GetTeamInformation(loading_gadget)
  logging.info(util.serialize(team_info))
  if loading_gadget.status == '1':
    root_blip = wavelet.root_blip
    props = {
        'team1': team_info['team1'],
        'match': team_info['match'],
        'team2': team_info['team2'],
        'action': team_info['action'],
        'location': team_info['location'],
        'match_date': team_info['match_date'],
        'status': 'New'
    }

    match_date = datetime.fromtimestamp(team_info['match_date'] / 1000)
    location = team_info['location']


    #RemoveDefaultTitleAndLink(root_blip)
    ChangeDefaultTitleStyle(root_blip)
    RemoveDefaultLink(root_blip)

    # Add Welcome message.
    # TODO Need to implement timezone specific logic.
    aus_date = match_date + timedelta(hours=2)

    # Adding action specific gadget.
    if team_info['action'] == 'party':
      # Add 'Match party' sub title and gadget.
      appendWelcomeInfo(root_blip, location, aus_date, WELCOME_TEXT_PARTY)
      appendSectionTitle(root_blip, 'Plan a viewing party!')
      appendContent(root_blip, 'When:')
      appendContent(root_blip, 'Where:')
      logging.error('Adding Map gadget.')
      root_blip.append(element.Gadget(MAP_GADGET_URL, props))

      addLineBreak(root_blip)
      appendContent(root_blip, 'Are you coming?\n')
      root_blip.append(element.Gadget(YESNO_GADGET_URL, props))

    else:
      # Add 'Betting' sub title and gadget.
      appendWelcomeInfo(root_blip, location, aus_date, WELCOME_TEXT)
      appendSubTitle(root_blip, 'Predict this match!')
      logging.error('Adding Betting gadget.')
      root_blip.append(element.Gadget(PREDICTION_GADGET_URL, props))

      addLineBreak(root_blip)

      # Add 'Player of the match' sub title and gadget.
      appendSubTitle(root_blip, 'Player of the match!')
      logging.error('Adding Favorite player gadget.')
      root_blip.append(element.Gadget(FAV_PLAYER_URL, props))

      addLineBreak(root_blip)

      # Add 'Player of the match' sub title and gadget.
      appendSubTitle(root_blip, 'Custom Polls! (thumbs up/down)')
      root_blip.append(element.Gadget(POLL_GADGET_URL, props))

    addLineBreak(root_blip)

    # Add 'RSS gadget' gadget and 'Live Feeds!' section title.
    appendSectionTitle(root_blip, 'Live Feeds!')
    logging.error('Adding RSS gadget.')
    root_blip.append(element.Gadget(RSS_GADGET_URL, props))

    # Add 'Twitter' gadget and 'Live Feeds!' section title.
    appendSectionTitle(root_blip, '')
    logging.error('Adding Twitter.')
    root_blip.append(element.Gadget(TWITTER_URL, props))

    logging.error('Gadgets added in root blip.')

  # Add footer text.
  appendContentInline(root_blip, '\nThis wave created by Football Fever. ')

  # Add footer link.
  appendLink(root_blip, 'Make your own!', 'http://wave.google.com/footballfever.html')

  # TODO thangaraju@google.com The loading gadget could be deleted.
  logging.error('The loading gadget could be deleted now.')
  loading_gadget.delete()
  pass


def ChangeDefaultTitleStyle(blip_ins):
  for ann in blip_ins.annotations:
    if ann.name == 'conv/title':
      blip_ref = blip_ins.range(ann.start, ann.end)
      blip_ref.annotate(blip.Annotation.FONT_FAMILY, 'Arial')
      blip_ref.annotate(blip.Annotation.FONT_WEIGHT, 'bold')
      blip_ref.annotate(blip.Annotation.FONT_SIZE, '18px')

def RemoveDefaultLink(blip_ins):
  for ann in blip_ins.annotations:
    logging.info(ann)
    if ann.name == 'link/manual':
      try:
        blip_ref = blip_ins.range(ann.start, ann.end)
        blip_ref.delete()
        logging.info('blip_ref deleted')
      except:
        logging.error('blip_ref')
        logging.error(blip_ref)
        pass


def RemoveDefaultTitleAndLink(blip_ins):
  to_be_removed = []
  for ann in blip_ins.annotations:
    if ann.name == 'link/manual' or ann.name == 'conv/title':
    #if ann.name == 'conv/title':
      to_be_removed.append(blip_ins.range(ann.start, ann.end))
  logging.error(to_be_removed)
  to_be_removed.reverse()
  logging.error(to_be_removed)
  for item in to_be_removed:
    try:
      logging.error(item)
      logging.error(item.get('name', ''))
      logging.error(item.get('value', ''))
      item.delete()
    except:
      pass

def OnGadgetStateChanged(event, wavelet):
  logging.info('OnGadgetStateChanged event:')
  logging.info(util.serialize(event))
  logging.info('wavelet')
  logging.info(util.serialize(wavelet))

  loading_gadget = GetLoadingGadget(event, wavelet)

  if IsGadget(loading_gadget):
    """ Loads at first time only. """
    LoadingGadgetStateChanged(event, wavelet, loading_gadget)


def IsGadget(gadget):
  try:
    if gadget.status == '1':
      logging.error('Success')
      return True
    else:
      logging.info(gadget.status)
      return False
  except:
    logging.info('Exception')
    return False


def OnAnnotationChanged(event, wavelet):
  """Called when the annotation changes."""
  blip_ins = event.blip
  logging.info('AnnotationChanged')


def GetRSSGadget(event, wavelet):
  """Get Loading Gadget."""
  blip_ins = event.blip
  gadget = blip_ins.first(element.Gadget, url=RSS_GADGET_URL)
  return gadget


def GetLoadingGadget(event, wavelet):
  """Get Loading Gadget."""
  blip_ins = event.blip
  gadget = blip_ins.first(element.Gadget, url=LOADING_GADGET_URL)
  return gadget


def parse_query(url):
  """ TODO use urlparse.parse_qs and remove this function """
  parse_result = urlparse.urlparse(url, True)
  url = parse_result.query
  key_values = url.split('&')
  query = dict()
  for item in key_values:
    item_key_value = item.split('=')
    key = item_key_value[0] or ''
    value = item_key_value[1] or ''
    if key:
      query[key] = value
  return query


def GetTeamInformation(loading_gadget):
  """Get Loading Gadget."""
  referer = loading_gadget.wavethis_referer or ''
  logging.info(referer)
  query = parse_query(referer)
  return {
    'team1': query['team1'] or 'No team1',
    'team2': query['team2'] or 'No team2',
    'action': query['action'] or '',
    'match': query['match'] or '0',
    'location': query['location'] or '',
    'match_date': int(query['matchDate']) or None
    }


def AddParticipant(wavelet, participant_id):
  participants = wavelet.participants
  if not participants.__contains__(participant_id):
    participants.add(participant_id.encode('utf-8'))


def UpdateParentWave(parent_wavelet, bug_id, status):
  """Update reference wave."""
  logging.info('UpdateParentWave')


if __name__ == '__main__':
  fifa_robot = robot.Robot('Football Fever - Worldcup 2010', image_url=ICON, profile_url='http://wave.google.com/footballfever.html')
  fifa_robot.register_handler(events.WaveletSelfAdded, OnWaveletSelfAdded)
  fifa_robot.register_handler(events.AnnotatedTextChanged,
                              OnAnnotationChanged,
                              filter=ROBOT_KEY)
  fifa_robot.register_handler(events.GadgetStateChanged, OnGadgetStateChanged)
  appengine_robot_runner.run(fifa_robot, debug=True)

